package service.impl;

import common.consts.Consts;
import dao.*;
import domain.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import service.ServiceResponse;
import service.UserProfileService;
import wrapper.CompleteApplierProfile;
import wrapper.UserWorkExperience;
import wrapper.user.CompleteUserProfile;
import wrapper.user.SimpleAccount;

import java.util.*;

/**
 * Created by liuchang on 2015/6/27.
 */
@Service
public class UserProfileServiceImpl extends ServiceBase implements UserProfileService {

    @Autowired
    private UserProfileDao userProfileDao;
    @Autowired
    private AccountDao accountDao;
    @Autowired
    private UserDataProfileDao dataProfileDao;
    @Autowired
    private OfferDao offerDao;
    @Autowired
    private WorkExperienceDao experienceDao;
    @Autowired
    private RecruitmentTypeDao typeDao;
    @Autowired
    private EducationDao educationDao;
    @Autowired
    private CompanyDao companyDao;

    @Override
    @Transactional
    public ServiceResponse modifyUserProfile(UserProfile userProfile) {
        Account account = accountDao.get(userProfile.getId());
        if (account == null) {
            return ServiceResponse.fail(Consts.i18nKey.INVALID_USERNAME);
        }

        updateProfile(userProfile, account);
        return ServiceResponse.success();
    }

    private void updateProfile(UserProfile userProfile, Account account) {
        UserProfile profile = userProfileDao.get(account.getId());
        boolean isNew = false;
        if (profile == null) {
            isNew = true;
        }

        String name = userProfile.getName();
        String gender = userProfile.getGender();
        String province = userProfile.getProvince();
        Integer age = userProfile.getAge();
        Date birthday = userProfile.getBirthday();
        String city = userProfile.getCity();
        String district = userProfile.getDistrict();
        Integer height = userProfile.getHeight();
        String phone = userProfile.getPhone();

        profile.setName(name == null ? "" : name);
        profile.setGender(gender == null ? "" : gender);
        profile.setProvince(province == null ? "" : province);
        profile.setAge(age == null ? 0 : age);
        profile.setBirthday(birthday == null ? account.getCreateTime() : birthday);
        profile.setCity(city == null ? "" : city);
        profile.setDistrict(district == null ? "" : district);
        profile.setHeight(height == null ? 0 : height);
        profile.setPhone(phone == null ? "" : phone);

        if (isNew) {
            profile.setId(account.getId());
            userProfileDao.insert(profile);
        } else {
            userProfileDao.update(profile);
        }
    }

    /**
     * 查看完整的 应聘者 的资料
     *
     * @param applier
     * @param viewer
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public ServiceResponse viewCompletedApplierProfile(long applier, long viewer, long recruitment) {
        Account account = accountDao.get(applier);
        if (account == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_USER);
        }
        Account viewerAccount = accountDao.get(viewer);
        if (viewerAccount == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_USER);
        }

        CompleteApplierProfile completeApplierProfile = new CompleteApplierProfile();

        //获取 基本资料
        UserProfile profile = userProfileDao.get(applier);

        //获取该用户基本的统计数据资料
        UserDataProfile dataProfile = dataProfileDao.get(applier);

        //检查 applier是否有应聘当前用户的工作，如果没有则需要隐藏applier的一些联系信息
        int num = offerDao.countOfferByApplierAndEmployer(applier, viewer);
        // 当前用户没有录用过 目标用户，所以只能看到简单的资料
        if (num <= 0) {
            profile.setName(Consts.NAME_MASK);
            profile.setPhone(Consts.PHONE_MASK);
            account.setUsername(Consts.NAME_MASK);
        }

        //获取applier的教育情况
        Education education = educationDao.get(applier);
        if (education == null) {
            education = new Education();
            education.setId(applier);
            educationDao.insert(education);
        }

        if (recruitment > 0) {
            Offer offer = offerDao.queryByApplierAndRecruitmentId(applier, recruitment);
            if (offer != null) {
                completeApplierProfile.setOffer(offer);
            } else {
                completeApplierProfile.setOffer(new Offer());
            }
        }

        completeApplierProfile.setAccount(SimpleAccount.from(account));
        completeApplierProfile.setUserProfile(profile);
        completeApplierProfile.setDataProfile(dataProfile);
        completeApplierProfile.setEducation(education);

        List<UserWorkExperience> uwes = getUserWorkExperiences(applier);

        completeApplierProfile.setWorkExperience(uwes);

        return ServiceResponse.success().with("completeProfile", completeApplierProfile);
    }

    @Override
    @Transactional
    public ServiceResponse getMyCompleteProfile(long user) {
        UserProfile profile = userProfileDao.get(user);
        Education education = educationDao.get(user);
        Company company = companyDao.findByOwner(user);

        CompleteUserProfile wrapper = new CompleteUserProfile();
        wrapper.setCompany(company);
        wrapper.setEducation(education);
        wrapper.setProfile(profile);
        return ServiceResponse.success().with("profile", wrapper);
    }

    @Override
    @Transactional(readOnly = false)
    public ServiceResponse updateProfileAndEducation(UserProfile userProfile, Education education) {
        long id = userProfile.getId();
        Account account = accountDao.get(id);
        if (account == null) {
            return ServiceResponse.fail(Consts.i18nKey.UNKNOWN_USER);
        }

        updateProfile(userProfile, account);
        updateEducation(education, id);

        return ServiceResponse.success();
    }

    private void updateEducation(Education education, long id) {
        Education eduDb = educationDao.get(id);
        boolean isNew = false;
        if (eduDb == null) {
            eduDb = new Education();
            isNew = true;
        }

        String school = education.getSchool();
        String grade = education.getGrade();
        String major = education.getMajor();

        eduDb.setSchool(school == null ? "" : school);
        eduDb.setGrade(grade == null ? "" : grade);
        eduDb.setMajor(major == null ? "" : major);

        if (isNew) {
            eduDb.setId(id);
            educationDao.insert(eduDb);
        } else {
            educationDao.update(eduDb);
        }
    }

    private List<UserWorkExperience> getUserWorkExperiences(long id) {
        Map<String, String> map = getRecruitmentTypeMap();

        List<UserWorkExperience> uwes = new ArrayList<>();
        List<WorkExperience> experiences = experienceDao.findExperiences(id);
        for (WorkExperience experience : experiences) {
            UserWorkExperience uwe = new UserWorkExperience();
            String category = experience.getCategory();
            uwe.setCode(category);
            uwe.setName(map.get(category));
            uwe.setTimes(experience.getTimes());
            uwes.add(uwe);
        }
        return uwes;
    }

    private Map<String, String> getRecruitmentTypeMap() {
        Map<String, String> typeMap = new HashMap<>();
        List<RecruitmentType> allTypes = typeDao.getTypeList();
        for (RecruitmentType type : allTypes) {
            typeMap.put(type.getCode(), type.getName());
        }
        return typeMap;
    }
}
